package com.ruoyi.web.controller.system;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.utils.CodeUtils;
import com.ruoyi.commonService.ThirdPartySmsService;
import com.ruoyi.sms.config.properties.JXSmsProperties;
import com.ruoyi.sms.core.JXSmsTemplate;
import com.ruoyi.sms.entity.JXSmsResult;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.SysRegisterService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Pattern;
import java.util.concurrent.TimeUnit;

import static com.ruoyi.common.constant.CacheConstants.CAPTCHA_CODE_KEY;

/**
 * 注册验证
 *
 * @author Lion Li
 */
@Validated
@RequiredArgsConstructor
@RestController
@SaIgnore
public class SysRegisterController extends BaseController {

    private final SysRegisterService registerService;
    private final ISysConfigService configService;

    private static final String SECRET_KEY = "your-256-bit-secret";
    private static final String TOKEN_HEADER = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ThirdPartySmsService smsService;
    @Autowired
    private ISysUserService userService;

    @Autowired
    private JXSmsProperties jxSmsProperties;

    /**
     * 用户注册
     */
    @SaIgnore
    @PostMapping("/register")
    public R<Void> register(@Validated @RequestBody RegisterBody user) {
        if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) {
            return R.fail("当前系统没有开启注册功能！");
        }
        registerService.register(user);
        return R.ok();
    }

    /**
     * 移动端注册发送验证码
     */
    @GetMapping("/captcha/mobileRegister")
    public R<Object> sendRegisterCode(
        @RequestParam @Pattern(regexp = "^1[3-9]\\d{9}$") String phone) {
        SysUser user = new SysUser();
        user.setPhonenumber(phone);
        if (!userService.checkPhoneUnique(user)) {
            return R.fail("验证码发送失败,该手机号已注册");
        }
        String code = CodeUtils.generateCode();
        redisTemplate.opsForValue().set("register:code:" + phone, code, 5, TimeUnit.MINUTES);

        // 调用第三方短信接口
        JXSmsTemplate jxSmsTemplate = new JXSmsTemplate(jxSmsProperties);
        String content = StrUtil.format(jxSmsProperties.getTemplate().get(2),
            MapBuilder.<String, Object>create()
                .put("code", code)
                .put("minute", 5)
                .build());
        if (jxSmsProperties.getEnabled()) {
            JXSmsResult jxSmsResult = jxSmsTemplate.sendMsg(phone, content);
            return R.ok("发送成功", jxSmsResult);
        } else {
            return R.ok("短信验证码发送成功", code);
        }
    }

    /**
     * 验证注册短信验证码
     *
     * @param phone 手机号
     * @param code  验证码
     * @return R
     */
    @GetMapping("/captcha/verifyRegisterSmsCode")
    public R<Void> verifyRegisterSmsCode(
        @RequestParam String phone,
        @RequestParam String code) {
        String storedCode = redisTemplate.opsForValue().get(
            "register:code:" + phone);
        if (!code.equals(storedCode)) {
            return R.fail("短信验证码有误");
        }
        redisTemplate.delete("register:code:" + phone);
        return R.ok("验证通过");
    }

    /**
     * 移动端注册
     */
    @PostMapping("/register/Mobile")
    public R<SysUser> registerUser(@RequestBody SysUser bo) {
        // 验证短信验证码,已在人脸前验证
//        String storedCode = redisTemplate.opsForValue().get(
//            "register:code:" + bo.getPhonenumber());
//        if (!bo.getSmsCode().equals(storedCode)) {
//            return R.fail("验证码有误");
//        }
        /*// 验证人脸识别结果
        if (!request.getFaceRecognitionResult().isVerified()) {
            return ResponseEntity.status(403).body("人脸识别未通过");
        }*/
        // 创建用户
        //SysUser user=new SysUser();
        bo.setRoleIds(new Long[]{2l});
        // user.setPhonenumber(request.getPhone());
        // user.setUserName(request.getUserName());
        Boolean bool = userService.registerUser(bo);
        return R.ok("注册成功", bo);
    }


    /**
     * 移动端登录发送
     */
    @GetMapping("/captcha/mobileLogin")
    public R<Object> sendMobileCaptcha(
        @RequestParam String phone) {
        String code = CodeUtils.generateCode();
        redisTemplate.opsForValue().set(CAPTCHA_CODE_KEY + phone, code, 5, TimeUnit.MINUTES);
//        smsService.sendSms(new SmsRequest(phone, code));

        JXSmsTemplate jxSmsTemplate = new JXSmsTemplate(jxSmsProperties);
        String content = StrUtil.format(jxSmsProperties.getTemplate().get(1),
            MapBuilder.<String, Object>create()
                .put("code", code)
                .put("minute", 5)
                .build());
        if (jxSmsProperties.getEnabled()) {
            JXSmsResult jxSmsResult = jxSmsTemplate.sendMsg(phone, content);
            return R.ok(jxSmsResult);
        } else {
            return R.ok("短信验证码发送成功", code);
        }
    }

    /**
     * 校验token是否有效
     */
    @GetMapping("/token/expired")
    public R<Boolean> expired(@RequestHeader("Authorization") String token) {
        try {
            String pureToken = token.replace("Bearer ", "");
            if (!StpUtil.getTokenInfo().getTokenValue().equals(pureToken)) {
                R.fail("非法Token", false);
            }
            //StpUtil.checkLogin();
            //boolean isValid =  !StpUtil.isDisable(pureToken);
            boolean isValid = StpUtil.isLogin() && !StpUtil.isDisable(StpUtil.getTokenValue());
            return isValid ? R.ok("Token有效", true) : R.fail("Token已失效", false);
        } catch (Exception e) {
            return R.fail("Token验证异常: " + e.getMessage(), false);
        }
    }


}
